// ------------------------------------------------------------------------------
// 
// Copyright (c) 2007-2008 Swampware, Inc.
// 
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// 
// ------------------------------------------------------------------------------
using System;

namespace wave
{
	/// <summary>
	/// Summary description for ErrorPrinter.
	/// </summary>
	public class ErrorPrinter
	{

		public static void PrintError(System.Exception exception, Water.List statements)
		{
			if(exception is System.Reflection.TargetInvocationException)
			{
				PrintError(exception.InnerException, statements);
			}
			else
			{
				PrintMessage(exception);
				PrintStatementStack(statements);
				PrintStackTrace(exception);

				if(exception.InnerException != null)
				{
					PrintMessage(exception.InnerException);
					PrintStackTrace(exception.InnerException);
				}
			}
		}

		private static void PrintMessage(System.Exception exception)
		{
			Water.Output.WriteLine();
			Water.Output.WriteLine();
			Water.Output.WriteLine(exception.Message);
			Water.Output.WriteLine();
		}

		private static void PrintStatementStack(Water.List statements)
		{
			if(statements.Count > 0)
			{
				Water.Output.WriteLine();
				Water.Output.WriteLine();

				int depth = 1;
				while(statements.Count > 0)
				{
					Water.Statement statement = (Water.Statement)statements.Dequeue();

					for (int i = 0; i < depth; i++)
					{
						Water.Output.Write("   ");
					}
					//TODO use a the actual text.
					Water.Output.Write(Water.Generator.QuickGenerate(statement.Expression));

					if (statement.File != null)
					{
						Water.Output.Write("   ");
						Water.Output.Write("[" + new System.IO.FileInfo((string)statement.File).Name + " (" + statement.Line + "," + statement.Column + ")]");
					}

					Water.Output.WriteLine();
					Water.Output.WriteLine();
					depth++;
				}
			}
		}

		private static void PrintStackTrace(System.Exception exception)
		{
			if(exception.StackTrace != null)
			{
				Water.Output.WriteLine();
				Water.Output.WriteLine();
				Water.Output.WriteLine(exception.StackTrace);
				Water.Output.WriteLine();
			}
		}

		private ErrorPrinter()
		{
		}

	}
}
